package robot.calibeta;

import lejos.nxt.SensorPort;
import lejos.nxt.addon.RFIDSensor;
import chair.Brain;
import chair.Chronos;
import chair.Organ;
import chair.core.Diary;
import chair.core.Stimulus;
import chair.core.Stimulus.StimulusType;

/**
 * Afin de pouvoir punir/récompenser le robot on utilise le capteur RFID. Le
 * robot est un fin esthète qui adore l'odore de fraise et exècre celle du
 * citron.
 * 
 * Comme le capteur RFID a besoin d'un certain délais entre deux requête on le
 * l'interrogera que toutes les RFID_POLLING_TIME milliseconds, en renvoyant la
 * précédente valeur entre-temps.
 * 
 * Si une balise n'est pas reconnue, on l'ignore et en maintient dernière
 * sensation.
 * 
 * RFID n'est lu que lorsque le robot est à l'arrêt, en "break".
 * 
 * @author nomhad
 * 
 */
public class OrganSmell extends Organ {

	/** Le capteur RFID dirigé vers l'avant sert d'odora */
	private RFIDSensor _smell;
	/**
	 * Pour gommer erreurs de lecture, renvoie dernière sensation si ne
	 * reconnaît pas balise
	 */
	private byte _lastSmell = 0;
	/**
	 * Combien de temps on attend entre chaque interrogation du capteur ?
	 * 
	 * NB: sert à rien de descendre sous 200ms, c'est le temps de
	 * RFIDSensor.DELAY_READ
	 * */
	private final long RFID_POLLING_TIME = 500;
	/** Quand a eu lieue la dernière lecture du capteur */
	private long _lastRead;

	public OrganSmell(Brain brain) {
		super(brain, "OrganSmell");
		_smell = new RFIDSensor(SensorPort.S1);
		// 1: fraise, 2: citron
		byte[] values = { 1, 2 };
		String[] names = { "MiamFraise", "BerkCitron" };
		registerValues(values, names);
		setStimulus(new Stimulus("Fraise", StimulusType.US, 1), (byte) 1);
		setStimulus(new Stimulus("Citron", StimulusType.US, -1), (byte) 2);
		setSpontaneous(true);
		// Le test dans sens() permettra au besoin lecture dès lancement
		// programme
		_lastRead = -RFID_POLLING_TIME;
	}

	/**
	 * Si une lecture est effectuée, ne renverra plus 0 tant que Motion est en
	 * break.
	 */
	@Override
	protected byte sense() {
		if (Motion.isOnABreak()) {
			byte[] values = null;
			if (Chronos.top() - _lastRead > RFID_POLLING_TIME) {
				values = _smell.readTransponder(true);
				_lastRead = Chronos.top();
			}
			// NB: values null si aucune balise ou si pas de lecture
			if (values != null) {
				Diary.log("RFID: [");
				for (int i = 0; i < values.length; i++)
					Diary.log(values[i] + ",");
				Diary.logln("]");
				// Fraise : 80,0,0,40,66
				// Citron : 80,0,93,-9,46
				// TODO: comme lit pas toujours très bien, on va utiliser que le
				// dernier byte
				if (values[4] == 66) {
					Diary.logln(this + " : miam de la fraise !");
					Voice.Melody.ZELDA_ITEM_FANFARE.play();
					_lastSmell = 1;
				} else if (values[4] == 46) {
					Diary.logln(this + " : berk du citron !");
					Voice.Melody.BEETHOVEN_SHORT.play();
					_lastSmell = 2;
				} else
					Diary.logln(this + " : connait pas.");
			}
		} else
			// Pas dans une période propice à la lecture : on assume le vide
			_lastSmell = 0;
		return _lastSmell;
	}
}
